//10.99.20.27:8080/eLaw/api/auth/token/get-token

// http://111.62.162.17:8081/dex-api/api/exchange/1433168907992039424
import java.util.regex.Pattern
import com.egova.lowcode.base.util.UserContext
import com.flagwind.application.Application
import com.egova.usercenter.config.NewVerAuthingClientProperties
import com.egova.api.util.http.HttpUtils;
import com.egova.json.utils.JsonUtils;
/**
 * 认证配置常量类
 */
final class AuthConstants {
    static final String ORIGIN_HEADER = 'origin'
    static final String TOKEN_HEADER = 'Authorization'
    static final String TOKEN_HEADER_NEW = 'Authorization'
    static final String COOKIE_HEADER = 'Cookie'
    static final String CAS_PREFIX = 'cas'
    static final String BEARER_PREFIX = 'Bearer'
    static final String BEARER_PREFIX_LOWER = BEARER_PREFIX.toLowerCase()
    static final List<String> SUPPORTED_CAS_TYPES = ['fac_access_token', 'egova-law-maven', 'eLaw']
    static final Map<String, String> COOKIE_TOKEN_PATTERNS = [
            'eUrbanToken'     : 'eUrbanToken',
            'admin_sso_token' : 'admin_sso_token',
            'cas_access_token': 'cas_access_token'
    ]
    static final String AUTH_TYPE = "auth_mis_elaw"
}

/**
 * Token工具类
 */
class TokenUtils {
    private final def tokenStore
    private final def out;
    private final def env;

    TokenUtils(tokenStore, env, out) {
        this.tokenStore = tokenStore
        this.out = out
        this.env = env
    }

    /**
     * 从Header中提取Token信息
     */
    def extractTokenFromHeader(String headerValue) {
        if (!headerValue) return null

        if (headerValue.contains(":") && headerValue.contains("${AuthConstants.CAS_PREFIX} ")) {
            // 旧格式处理
            def arr = headerValue.split(":")
            return [
                    authorizationType: 'cas',
                    tokenType        : arr[0].split(" ")[1],
                    tokenValue       : arr[1]
            ]
        } else if (headerValue.startsWith(AuthConstants.BEARER_PREFIX) ||
                headerValue.startsWith(AuthConstants.BEARER_PREFIX_LOWER)) {
            // Bearer token处理
            def parts = headerValue.split(" ")
            if (parts.size() < 2) return null
            var properties = Application.resolve(NewVerAuthingClientProperties);
            this.out.println("用户中心2.0开启: ${properties.enabled}"); ;
            return [
                    authorizationType: 'Bearer',
                    tokenType        : properties.enabled ?
                            "admin_sso_token" : "sso_access_token",
                    tokenValue       : parts[1]
            ]
        }
        return null
    }

    /**
     * 从Cookie中提取Token信息
     */
    def extractTokenFromCookies(String cookieStr) {
        if (!cookieStr) return null
        for (entry in AuthConstants.COOKIE_TOKEN_PATTERNS) {
            def matcher = (cookieStr =~ /${entry.key}=([^;,\s]+)/)
            if (matcher.find()) {
                if (entry.value == "cas_access_token") {
                    def arr = matcher.group(1).split(":")
                    return arr.length >= 2 ? [
                            authorizationType: 'Bearer',
                            tokenType        : arr[0],
                            tokenValue       : arr[1]
                    ] : null
                } else {
                    return [
                            authorizationType: 'Bearer',
                            tokenType        : entry.value,
                            tokenValue       : matcher.group(1)
                    ]
                }
            }
        }
        return null
    }

    /**
     * 交换Token
     */
    def exchangeToken(url, tokenInfo) {
        if (!url) {
            throw ExceptionUtils.api("无效的token服务地址")
        }
        if (!tokenInfo?.tokenType || !tokenInfo?.tokenValue || !url) {
            throw ExceptionUtils.api("无效的token信息")
        }

        var res = HttpUtils.get(url, String.class);
        var body = JsonUtils.deserialize(res.getBody(), Map.class);
        var e = body['resultInfo']
        var dataTemp = e['data'];
        var token = dataTemp['token']
        return token

    }

    /**
     * 设置认证头
     */
    def setAuthHeader(request, tokenInfo) {
        request.removeHeader(AuthConstants.COOKIE_HEADER)
        if (tokenInfo.authorizationType == 'Bearer') {
            request.removeHeader(AuthConstants.TOKEN_HEADER)
            request.setHeader(AuthConstants.TOKEN_HEADER_NEW, "Bearer ${tokenInfo.tokenValue}")
        } else if (tokenInfo.authorizationType == 'cas') {
            request.removeHeader(AuthConstants.TOKEN_HEADER)
            request.setHeader(AuthConstants.TOKEN_HEADER_NEW, "cas ${tokenInfo.tokenType}:${tokenInfo.tokenValue}")
        } else if (tokenInfo.authorizationType == 'queryToken') {
            request.removeHeader(AuthConstants.TOKEN_HEADER)
            request.setHeader(AuthConstants.TOKEN_HEADER_NEW, tokenInfo.tokenValue)

        }

        out.println("==========================")
    }

    def getVariableWithUrl(String key, String defaultValue) {
        return this.env[key] ?: defaultValue;
    }

    def getVariableWithOther(String key, String defaultValue) {
        return (this.env[key] ?: "").replace("http://", "") ?: defaultValue;
    }
}

// 主处理逻辑
try {
    // 初始化TokenUtils（需要先获取tokenStore实例）
    // 注意：这里需要根据实际情况获取tokenStore实例

    def tokenUtils = new TokenUtils(tokenStore, variables['ENV'], out)

    // 1. 尝试从Header获取Token
    def tokenInfo = null
    def authHeader = request.getHeader(AuthConstants.TOKEN_HEADER)

    if (authHeader) {
        out.println("=========灵珑透传的token=========")
        out.println(authHeader)
        tokenInfo = tokenUtils.extractTokenFromHeader(authHeader)
    }

    // 2. 如果Header中没有，尝试从Cookie获取
    if (!tokenInfo) {
        out.println("没有获取透传的token,尝试从Cookie中获取token...")
        def cookieStr = request.getHeader(AuthConstants.COOKIE_HEADER)
        tokenInfo = tokenUtils.extractTokenFromCookies(cookieStr)
    }

    // 3. 验证Token有效性
    if (!tokenInfo?.tokenValue) {
        throw ExceptionUtils.api("未找到有效的token，无法进行身份验证！")
    }

    // 4. 检查是否支持的类型
    def isSupportedType = AuthConstants.SUPPORTED_CAS_TYPES.any { tokenInfo.tokenType.startsWith(it) }

    out.println("cas_type: ${tokenInfo.tokenType}");
    out.println("cas_token: ${tokenInfo.tokenValue}");

    if (isSupportedType) {
        out.println("isSupportedType");
        tokenInfo.authorizationType = 'queryToken';
        tokenUtils.setAuthHeader(request, tokenInfo);
        return
    }

    def exchangeEndpoint = tokenUtils.getVariableWithUrl('svc_token_mis_elaw', null)

    if (!exchangeEndpoint) {
        throw ExceptionUtils.api("没有配置token交换协议服务地址,无法获取服务token")
    }

    // 5. 对于不支持的类型，进行Token交换
    try {
        out.println("=========Token交换=========")
        out.println("auth-type:${AuthConstants.AUTH_TYPE}");
        out.println("endpoint:${exchangeEndpoint}");
        def newToken = tokenUtils.exchangeToken(exchangeEndpoint, tokenInfo);
        out.println("获取新token: ${newToken}");
        def newTokenInfo = [
                authorizationType: 'queryToken',
                tokenType        : AuthConstants.AUTH_TYPE,
                tokenValue       : newToken
        ];
        tokenUtils.setAuthHeader(request, newTokenInfo);
    } catch (Exception e) {
        throw ExceptionUtils.api("交换处理失败: ${e.message}");
    }
} catch (Exception e) {
    throw ExceptionUtils.api("Token处理失败: ${e.message}");
}
